﻿using System;
using System.Collections.Generic;
using System.Data.SQLite;
using SimpleOrmCFPC.Core.RequestsComputer.Dialects;
using SimpleOrmCFPC.Tests.acceptance.Sqlite;
using SimpleOrmCFPC.upgrade;

namespace SimpleOrmCFPC.engines.sqlite
{
        public class SQLiteTableSchemaProvider : ISchemaProvider
        {
            private SQLiteConnection cnn;

            public SQLiteTableSchemaProvider(SQLiteConnection sqliteConnection)
            {
                cnn = sqliteConnection;
            }

            public TableMapping GetTableSchema(string tableName)
            {
                var cmd = cnn.CreateCommand();
                cmd.CommandText = string.Format("pragma table_info({0})", tableName);

                var schema = new TableMapping();
                schema.Name = tableName;
                var reader = cmd.ExecuteReader();
                while (reader.Read())
                {
                    var column = new ColumnMapping(reader.GetString(1), reader.GetBoolean(5), reader.GetBoolean(3), false, ExtractDbType(reader.GetString(2)), ExtractMaxLength(reader.GetString(2)));
                    schema.Columns.Add(column);
                }
                if (schema.Columns.Count == 0)
                    throw new TableNotFoundException(tableName);
                return schema;
            }

            private int ExtractMaxLength(string typeDb)
            {
                var typeSplitted = typeDb.Split('(');
                if (typeSplitted.Length <= 1)
                    return 0;
                return Int32.Parse(typeSplitted[1].Replace(")", ""));
            }

            private DbType ExtractDbType(string typeDb)
            {
                var type = typeDb.Split('(')[0].Trim().ToLower();
                var types = new Dictionary<string, DbType>
                    {
                        {"varchar", DbType.Char},
                        {"bigint", DbType.Bigint},
                        {"integer", DbType.Integer},
                        {"float", DbType.Float},
                        {"datetime", DbType.Date}
                    };
                return types[type];
            }

            public bool TableExists(string tableName)
            {
                try
                {
                    GetTableSchema(tableName);
                    return true;
                }
                catch (Exception)
                {
                    return false;
                }
            }
        }
    
}
